<?php

namespace App\Console\Commands;

use App\Models\Base\LogVipRemain;
use App\Service\AccountService;
use App\Service\ChannelService;
use App\Service\OrderService;
use App\Service\PlayerService;
use App\Service\ServerService;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class FetchVipRate extends CommandBase
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'fetch:vipRate {dateTime?}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'vip留存统计';

    /**
     * @var Model
     */
    protected $model;

    protected $rate_day;

    /**
     * Create a new command instance.
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $dateTime = $this->argument('dateTime');
        if ($dateTime) {
            $this->today = $dateTime;
            $this->todayTimestamp = strtotime($dateTime);
            $this->yesterdayTimestamp = $this->todayTimestamp - 86400;
            $this->yesterday = date('Y-m-d', $this->yesterdayTimestamp);
        }
        $this->rate_day = [
            1 => 'two_rate',
            2 => 'three_rate',
            3 => 'four_rate',
            4 => 'five_rate',
            5 => 'six_rate',
            6 => 'seven_rate',
            14 => 'fifteen_rate',
            29 => 'thirty_rate',
        ];

        //统计全平台
        $this->platformAllStat();
        //渠道统计
        $this->channelStat();
        $this->serverStat();
    }

    /**
     * 全平台vip用户留存统计
     */
    protected function platformAllStat()
    {
        $this->model = new LogVipRemain();
        $this->model->type = self::STAT_TYPE_PLATFORM;
        $this->model->date_time = $this->yesterday;
        $user_ids = $this->getRegisterUser();
        $pay_users = OrderService::payUsers($user_ids, $this->yesterdayTimestamp, $this->todayTimestamp);
        if ($pay_users->isNotEmpty()) {
            $pay_user_ids = $pay_users->pluck('channel_id', 'userid')->all();

            $this->recordPayUser($pay_user_ids);
        }
        //付费用户数量
        $pay_user_number = $pay_users->count();
        $this->model->new_pay_users = $pay_user_number;
        $this->model->save();

        //更新留存数据
        foreach ($this->rate_day as $day => $rate_key) {
            $bygone_yesterday = Carbon::parse($day + 1 .' days ago')->toDateString();
            $rate_result = LogVipRemain::where('date_time', $bygone_yesterday)
                ->where('type', self::STAT_TYPE_PLATFORM)->first();
            if (!$rate_result || 0 == $rate_result->new_pay_users) {
                continue;
            }

            $this->updateBygoneRateUser($bygone_yesterday, $rate_result, $rate_key);
        }
    }

    /**
     * 按渠道统计
     */
    protected function channelStat()
    {
        $channel_ids = ChannelService::getChannels();
        if ($channel_ids->isEmpty()) {
            return false;
        }
        foreach ($channel_ids as $channel_id) {
            $this->model = new LogVipRemain();
            $this->model->type = self::STAT_TYPE_CHANNEL;
            $this->model->channel_id = $channel_id;
            $this->model->date_time = $this->yesterday;
            $user_ids = $this->getChannelRegisterUser($channel_id);
            $pay_user_number = OrderService::payUsers($user_ids, $this->yesterdayTimestamp, $this->todayTimestamp)->count();
            $this->model->new_pay_users = $pay_user_number;
            $this->model->save();
            foreach ($this->rate_day as $day => $rate_key) {
                $rate_day = Carbon::parse($day + 1 .' days ago')->toDateString();
                $rate_result = LogVipRemain::where('date_time', $rate_day)
                    ->where('channel_id', $channel_id)->first();
                if (!$rate_result || 0 == $rate_result->new_pay_users) {
                    continue;
                }
                $this->updateBygoneRateUser($rate_day, $rate_result, $rate_key, $channel_id);
            }
        }
    }

    /**
     * 区服统计
     *
     * @return bool
     */
    protected function serverStat()
    {
        $server_ids = ServerService::serverIds();
        if ($server_ids->isEmpty()) {
            return false;
        }
        foreach ($server_ids as $server_id) {
            setDB($server_id);
            $this->model = new LogVipRemain();
            $this->model->server_id = $server_id;
            $this->model->type = self::STAT_TYPE_SERVER;
            $pay_role_ids = $this->getPayRoles();
            $this->model->new_pay_users = count($pay_role_ids);
            $this->model->date_time = $this->yesterday;
            $this->model->save();
            //记录付费角色创建时间
            $this->recordPayRole($pay_role_ids, $server_id);
            //更新往日记录
            foreach ($this->rate_day as $day => $rate_key) {
                $rate_day = Carbon::parse($day.' days ago');
                $rate_yesterday = Carbon::parse($day + 1 .' days ago');
                $rate_result = LogVipRemain::where('date_time', $rate_yesterday->toDateString())
                    ->where('server_id', $server_id)->first();
                if (!$rate_result || 0 == $rate_result->new_pay_users) {
                    continue;
                }
                $vip_role_ids = $this->updateServerVipRoleRate($rate_yesterday->toDateString(), $server_id);
                $rate_user_number = PlayerService::playerLoginCount($rate_yesterday->timestamp,
                    $rate_day->timestamp, $vip_role_ids)->count();
                $rate_result->$rate_key = $rate_user_number / $rate_result->new_pay_users;
                $rate_result->save();
            }
        }
    }

    /**更新区服留存
     * @param $rate_day
     * @param $server_id
     * @return array
     */
    private function updateServerVipRoleRate($rate_day, $server_id)
    {
        $vip_role_ids = [];
        $vip_roles = PlayerService::somedayLoginVipRole($rate_day, $server_id);
        if ($vip_roles->isNotEmpty()) {
            $vip_role_ids = $vip_roles->pluck('role_id')->all();
        }

        return $vip_role_ids;
    }

    /**
     * 记录付费角色创建时间.
     *
     * @param array $role_ids
     * @param $server_id
     *
     * @return bool
     */
    private function recordPayRole(array $role_ids, $server_id)
    {
        if (empty($role_ids)) {
            return false;
        }
        $attributes = [];
        foreach ($role_ids as $role_id) {
            $attributes[] = [
                'date_time' => $this->yesterday,
                'server_id' => $server_id,
                'role_id' => $role_id,
            ];
        }

        return DB::table('log_vip_sign_roles')->insert($attributes);
    }

    /**
     * 昨日付费角色id集合.
     *
     * @return array
     */
    private function getPayRoles()
    {
        $role_ids = $palyer_ids = [];
        //新增角色数量
        $new_role = PlayerService::getSignPlayer($this->yesterdayTimestamp, $this->todayTimestamp);

        if ($new_role->isEmpty()) {
            return $role_ids;
        } else {
            $role_ids = $new_role->pluck('id')->all();
        }

        $orders = OrderService::getUserByRoleId($role_ids);

        if (!$orders->isEmpty()) {
            $player_ids = $orders->pluck('player_id')->all();
        }

        return $player_ids;
    }

    /**
     * 更新往日留存数据.
     *
     * @param $rate_day
     * @param LogVipRemain $rate_result
     * @param $rate_key
     * @param null $channel_id
     */
    private function updateBygoneRateUser($rate_day, LogVipRemain $rate_result, $rate_key, $channel_id = null)
    {
        //往日登录VIP用户
        $vipUsers = AccountService::somedayLoginVipUser($rate_day, $channel_id);

        if ($vipUsers->isNotEmpty()) {
            $vipUserIds = $vipUsers->pluck('user_id')->all();
            $rate_login_user = AccountService::loginByUserIds($vipUserIds, $this->yesterdayTimestamp,
                $this->todayTimestamp)->count();
        } else {
            $rate_login_user = 0;
        }
        //更新留存
        $rate_result->$rate_key = $rate_login_user / $rate_result->new_pay_users;
        $rate_result->save();
    }

    /**
     * 记录每日付费用户.
     *
     * @param array $user_ids
     *
     * @return bool
     */
    private function recordPayUser(array $user_ids = [])
    {
        if (empty($user_ids)) {
            return false;
        }
        $attributes = [];
        foreach ($user_ids as $user_id => $channel_id) {
            $attributes[] = [
                'date_time' => $this->yesterday,
                'channel_id' => $channel_id,
                'user_id' => "{$user_id}",
            ];
        }

        return DB::table('log_vip_sign_users')->insert($attributes);
    }

    /**
     * 获取昨日渠道注册用户user_id集合.
     *
     * @param $channel_id
     *
     * @return array
     */
    private function getChannelRegisterUser($channel_id)
    {
        $user_ids = [];
        $new_users = ChannelService::registerUsers($this->yesterdayTimestamp, $this->todayTimestamp, $channel_id);
        if (!$new_users->isEmpty()) {
            $user_ids = $new_users->pluck('ac_id')->all();
        }

        return $user_ids;
    }

    /**
     * 获取昨日全平台注册用户user_id集合.
     *
     * @return array
     */
    private function getRegisterUser()
    {
        $user_ids = [];
        $new_users = AccountService::signNumber($this->yesterdayTimestamp, $this->todayTimestamp);
        if (!$new_users->isEmpty()) {
            $user_ids = $new_users->pluck('ac_id')->all();
        }

        return $user_ids;
    }
}
